module.exports = function(a,tcb){
  var _this = tcb ? tcb : {};
  var env = '';
  var apiurl = 'https://tcb-api.tencentcloudapi.com/web?env=';
  var access_token = '';
  var access_token_expire = 3500000;
  var login_type = '';
  var uuid = '';
  var hosting = '';
  _this.userInfo = _this.userInfo || {};
  _this.init = _this.init || function(args){
    env = args.env;
    hosting = args.hosting
    apiurl += env;
    return _this;
  }
  function ajax(data){
    return new Promise(function(next){
      data.seqId = env + new Date().getTime() + a.zIndex();
      data.env = env;
      function _ajax(data){
        if(a.platform == 'WeChatMiniApp'){
          wx.request({
            url: apiurl,
            method:'POST',
            data:data,
            header:{
              userid:uuid,
              origin:hosting
            },
            success: function(ret){
              next(ret.data,data);
            },
            fail:function(err){
              next({errorMsg:err.toString()},data);
            }
          })
        }else{
          new a.Ajax(apiurl,function(ret){
            next(ret,data);
          },{
            meth:'POST',
            data:data
          }).action()
        }
      }
      _ajax(data);
    })
  }
  _this.auth = _this.auth || function(next){
    return {
      fetchAccessTokenWithRefreshToken:function(next){
        ajax({
          action:'auth.fetchAccessTokenWithRefreshToken',
          refresh_token:access_token
        }).then((ret,data) => {
          access_token = ret.access_token;
          access_token_expire = ret.access_token_expire;
          login_type = ret.login_type;
          if(typeof next == 'function') next();
        })
      },
      signInAnonymously:function(next){
        if(a.platform == 'WeChatMiniApp' && tcb){
          if(typeof next == 'function') next();
          return false;
        }
        ajax({
          action:'auth.signInAnonymously',
          anonymous_uuid:uuid,
          refresh_token:uuid + new Date().getTime(),
        }).then((ret,data) => {
          access_token = ret.refresh_token;
          access_token_expire = ret.access_token_expire;
          uuid = ret.uuid;
          this.fetchAccessTokenWithRefreshToken(function(){
            ajax({
              action:'auth.getUserInfo',
              access_token
            }).then((ret,data) => {
              _this.userInfo = ret.data;
              if(typeof next == 'function') next();
            })
          })
        })
      }
    }
  }
  _this.callFunction = _this.callFunction || function(args){
    return new Promise(function(resolve, reject){
      ajax({
        action:'functions.invokeFunction',
        access_token,
        function_name:args.name,
        request_data:JSON.stringify(args.data)
      }).then((ret,data) => {
        try{
          if(ret.code == 'ACCESS_TOKEN_EXPIRED'){
            resolve({result:{code:400,errorMsg:'登录超时'}});
          }else{
            ret = JSON.parse(ret.data.response_data);
            resolve({result:ret});
          }
        }catch(e){
          reject({errorMsg:e.toString()})
        }
      })
    })
  }
  _this.getUploadMetadata = function(cloudPath){
    return ajax({
      action:'storage.getUploadMetadata',
      path:cloudPath
    })
  }
  _this.uploadFile = _this.uploadFile || function(args){
    return new Promise(function(resolve, reject){
      _this.getUploadMetadata(args.cloudPath).then(ret => {
        try{
          if(!ret.data){
            resolve({errorMsg:ret.message || ret.code || '获取上传地址失败'})
            return false;
          }
          ret = ret.data;
          var seqId = env + new Date().getTime() + a.zIndex()
          if(a.platform == 'WeChatMiniApp'){
            wx.uploadFile({
              filePath: args.filePath,
              name: 'file',
              url: ret.url,
              header:{
                'X-SDK-Version':'1.10.6',
                'x-seqid':seqId
              },
              formData:{
                key:args.cloudPath,
                signature:ret.authorization,
                'x-cos-meta-fileid':ret.cosFileId,
                success_action_status:201,
                'x-cos-security-token':ret.token,
                key:args.cloudPath,
                seqId:seqId
              },
              success(xml){
                resolve({url:ret.download_url})
              }
            })
          }else{
            var formData = new FormData();
            formData.append('key', args.cloudPath);
            formData.append('signature', ret.authorization);
            formData.append('x-cos-meta-fileid', ret.cosFileId);
            formData.append('success_action_status', 201);
            formData.append('x-cos-security-token', ret.token);
            formData.append('seqId', seqId);
            formData.append('key', args.cloudPath);
            formData.append('file', args.filePath, args.cloudPath);
            a.ajax(ret.url,function(xml){
              resolve({url:ret.download_url})
            },{
              UNTCB:true,
              unAjaxHeader:true,
              header:[
                {value:'1.10.6',key:'X-SDK-Version'},
                {value:seqId,key:'x-seqid'}
              ],
              dataType:'xml',
              noLoginAction:true,
              meth:'POST',
              data:formData
            })
          }
        }catch(e){
          reject({errorMsg:e.toString()})
        }
      })
    })
  }
  _this.getTempFileURL = _this.getTempFileURL || function(){

  }
  
  _this.ajax = function(router,next,args){
    args = args || {};
    router = router.split('?');
    var meth = args.meth || 'GET';
    var query = router[1] || '';
    query = query ? a.string(query).urlParse() : {};
    if(/GET|DELETE/.test(meth) && args.data) a.merge(query,args.data);
    var headers = {};
    try{
      if(args.unAjaxHeader !== true){
        var ajaxHeader = a.Storage.get('ajaxHeader');
        for(i = 0; i < ajaxHeader.length; i++) headers[ajaxHeader[i].key] = ajaxHeader[i].value;
      }
    }catch(e){}
    if(args.header) for(var i = 0; i < args.header.length; i ++) headers[args.header[i].key] = args.header[i].value;
    router = meth.toUpperCase() + router[0].replace(/\//g,'-');
    if(args.loading && args.loading.open) args.loading.open();
    function result(ret){
      next(ret);
      if (args.errNotify !== false && ret.errorMsg) {
        a.showToast({
          title: '成功',
          icon: 'none',
          duration: 2000,
          title: ret.errorMsg.toString()
        })
      }
      if(args.loading && args.loading.close) args.loading.close();
    }
    try{
      _this.callFunction({
        name: args.callfunction || 'TCBExpress',
        data:{
          router,
          headers,
          platform:a.platform,
          query,
          sql:args.data && args.data.sql ? args.data.sql : null,
          body:args.data
        }
      }).then(function(ret){
        var loginAction = a.Storage.get('loginAction');
        if(loginAction && !args.noLoginAction) {
          loginAction.call(null,ret.result,result);
        }else{
          result(ret.result);
        }
      }).catch(function(e){
        console.log(e);
        result({errorMsg:e});
      })
    }catch(e){
      console.log(e);
      result({errorMsg:e});
    }
  }
  _this.list = function(args){
    args = args || {};
    if(typeof args.get == 'string'){
      args.get = {
        url:args.get,
        data:{}
      }
    }else if(args.get && typeof args.get == 'object'){
      args.get = {
        url:args.get.url,
        data:args.get.data
      }
    }
    if(args.get && !args.get.action){
      args.get.action = function(key,next){
        _this.ajax(this.url,next,{data:this.data});
      }
    }
    return new a.List(args);
  }
  _this.upload = function(fileObject, ajaxConfig,next){
    var uploadData = {cloudPath: fileObject.name};
    if(a.platform == 'WeChatMiniApp'){
      uploadData.filePath = fileObject.path;
    }else{
      fileObject.blob.name = fileObject.name;
      fileObject.blob.lastModifiedDate = new Date();
      uploadData.filePath = fileObject.blob;
    }
    _this.uploadFile(uploadData).then(ret => {
      if(ret.fileID){
        _this.getTempFileURL({fileList: [ret.fileID]}).then(ret => {
          next({url:ret.fileList[0].tempFileURL});
        }).catch(err => {
          next({errorMsg:ret.errMsg || '上传出错,获取地址失败'})
        })
      }else if(ret.url){
        next(ret)
      }else{
        next({errorMsg:ret.errMsg || '上传出错'})
      }
    }).catch(err => {
      next({errorMsg:err.toString()})
    })
  }
  return _this;
}